package aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component("myAspect") //将切面对象交给Spring容器管理
@Aspect //声明当前类是一个切面类
public class MyAspect {

    /**
     * 切点表达式抽取
     */
    @Pointcut("execution(* aop..*.*(..))")
    public void myPointcut(){}

    /**
     * 前置增强
     */
//    @Before("execution(* aop..*.*(..))")
    @Before("myPointcut()")
    public void before(){
        System.out.println("前置增强方法执行...");
    }

    /**
     * 后置增强
     */
    @AfterReturning("execution(* aop..*.*(..))")
    public void afterReturning(){
        System.out.println("后置增强方法执行...");
    }

    /**
     * 环绕增强
     * @param pjp 正在执行的连接点(切点)
     */
    public Object around(ProceedingJoinPoint pjp){
        try {
            System.out.println("环绕前增强方法执行...");
            //执行切点方法
            Object ret = pjp.proceed();
            System.out.println("环绕后增强方法执行...");
            return ret;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            return null;
        }
    }

    /**
     * 异常抛出增强
     */
    public void afterThrowing(){
        System.out.println("异常抛出增强...");
    }

    /**
     * 最终增强，无论是否抛异常都会执行
     */
    public void after(){
        System.out.println("最终增强方法执行...");
    }
}
